package com.mew.chess.core.common.handler;

import com.mew.common.config.SpringContextBean;
import com.mew.common.exception.ResponseCode;
import com.zebra.common.ZebraException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;

import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


@Component
@Slf4j
public class InitializeStartMapping {

    private final static ConcurrentHashMap<String, ChessStart> handlerMapping = new ConcurrentHashMap<>();

    public static ChessStart getMapping(String vfx) throws ZebraException {
        if (handlerMapping.isEmpty()){
            try {
                initializeMapping();
            } catch (Exception e) {
                throw new ZebraException(ResponseCode.SysException.code(), "chess InitializeStartMapping analysis handler error!");
            }
        }
        return handlerMapping.get(vfx);
    }


    public static void initializeMapping()throws Exception{
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AnnotationTypeFilter(ChessStartAnnotation.class));
        Set<BeanDefinition> components = provider.findCandidateComponents("com/mew/chess/core/game");
         for (BeanDefinition component : components) {
             Class clazz =  Class.forName(component.getBeanClassName());
             if(clazz.isAnnotationPresent(ChessStartAnnotation.class)){
                 ChessStartAnnotation chessHandler = (ChessStartAnnotation) clazz.getAnnotation(ChessStartAnnotation.class);
                 putMapping(chessHandler.value(), clazz);
             }
         }

        log.info("Initialize StartMapping success {} ", handlerMapping.size());
    }

    private static void putMapping(String vfx, Class<ChessStart> clazz)throws  Exception{
        if (null == clazz || StringUtils.isEmpty(vfx)){
            throw new Exception("build game start exception");
        }
        handlerMapping.put(vfx, Optional.ofNullable(SpringContextBean.getBean(clazz)).orElseThrow(()-> new Exception("build chess start handlerMapping,no exception")));
    }



}
